package manager

import event.CargoEvent
import event.InventoryChangedEvent
import ext.log
import mvc.model.inventory.WaresInfo
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import org.json.JSONObject
import protocol.BaseProtocol
import serialport.DeliverPortManager
import java.util.concurrent.CopyOnWriteArrayList
import java.util.concurrent.LinkedBlockingQueue
import java.util.concurrent.TimeUnit


object WaresManager : Runnable {
    var SelectIndex = -1

    private val WareInfos = CopyOnWriteArrayList<WaresInfo>()
    private val queue = LinkedBlockingQueue<CargoEvent>()

    var size = WareInfos.size
        get() = WareInfos.size

    operator fun get(index: Int) = WareInfos[index]

    var selectInfo = WaresInfo.withEmpty()
        get() = WareInfos[SelectIndex]

    override fun run() {
        try {
            val result = HttpRequestManager.refreshInventory()
            log("--$result")
            val json = JSONObject(result)
            val arr = json.getJSONArray("arr")
            val length = arr.length()
            WareInfos.clear()
            for (i in 0 until length) {
                WareInfos.add(WaresInfo.withJson(arr.getJSONObject(i)))
            }
            EventBus.getDefault().register(this)
            syncCargo()
            while (true) {
                val env = queue.poll(1, TimeUnit.SECONDS)
                if (env == null) {
                    log("同步库存失败")
                    break
                }
                if ((env.col == 0) && (env.row == 0)) {
                    log("同步库存完成")
                    break
                }
                if (env.num == 2) {
                    log("清除货道:${env.row}-${env.col}")
                    clearByCargo("${env.row}-${env.col}")
                }
            }
            EventBus.getDefault().unregister(this)
            EventBus.getDefault().post(InventoryChangedEvent())
        } catch (e: Exception) {
            e.printStackTrace()
            TaskManager.DelayHandler.postDelayed(this, 5 * 1000)
        }
    }

    fun refreshAsync() {
        TaskManager.DelayHandler.post(this)
    }

    @Subscribe(threadMode = ThreadMode.POSTING)
    fun onCargoEvent(env: CargoEvent) {
        queue.put(env)
    }

    private fun clearByCargo(name: String) {
        WareInfos.forEach {
            if (it.clearByCargo(name)) {
                return
            }
        }
    }

    private fun syncCargo() {
        queue.clear()
        val buf = BaseProtocol(0x30)
            .build()
        DeliverPortManager.Instance.write(buf)
    }
}